﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Wormhole.Engine.CardLibrary.CardProperties;

namespace Wormhole.Engine.CardLibrary.BaseCardTypes
{
	/// <summary>
	/// The base class for cards that have skills, these include:
	/// Characters, Support Characters, Obstacles and Adversaries.
	/// </summary>
	public abstract class SkillsCard : CostCard
	{
		#region Delegates
		/// <summary>
		/// The delegate for the CardAssigned event.
		/// </summary>
		/// <param name="card">The card that was assigned.</param>
		public delegate void CardAssignedDelegate(SkillsCard card);

		/// <summary>
		/// The delegate to use for the event that will fire when the card status changes.
		/// </summary>
		/// <param name="status">The new card status.</param>
		public delegate void StatusChangedDelegate(CardStatus status);
		#endregion

		#region Events
		/// <summary>
		/// This event is fired when the card is assigned.
		/// </summary>
		public event CardAssignedDelegate CardAssigned;

		/// <summary>
		/// This event is fired when the card is unassigned.
		/// </summary>
		public event CardAssignedDelegate CardUnassigned;

		/// <summary>This event is fired when the card status changes.</summary>
		public event StatusChangedDelegate StatusChanged;
		#endregion

		#region Properties

		#region Status
		private CardStatus _status;
		/// <summary>
		/// The status of the card.
		/// </summary>
		public CardStatus Status
		{
			get
			{
				return this._status;
			}

			set
			{
				if (this._status != value)
				{
					this._status = value;
					this.OnStatusChanged(value);
				}
			}
		}
		#endregion

		#region Assigned
		/// <summary>
		/// Is the card assigned to a mission.
		/// </summary>
		public bool Assigned 
		{
			get
			{
				return (this.Status == CardStatus.Assigned);
			}

			set
			{
				if (value)
					this.Status = CardStatus.Assigned;
				else
					this.Status = CardStatus.Unassigned;
			}
		}
		#endregion

		#region Skills
		/// <summary>
		/// The skills the card has.
		/// </summary>
		public abstract Skills Skills { get; }
		#endregion

		#endregion

		#region Constructor
		/// <summary>
		/// Initialize a new instance of the class.
		/// </summary>
		/// <param name="owner">The card owner.</param>
		public SkillsCard(Player.Player owner)
			: base(owner)
		{
			this.Status = CardStatus.Unassigned;
		}
		#endregion

		#region Assign
		/// <summary>
		/// Assign the card to a mission.
		/// </summary>
		public void Assign()
		{
			if (this.CanAssign())
			{
				this.Assigned = true;
				this.OnCardAssigned();
			}
		}
		#endregion

		#region Unassign
		/// <summary>
		/// Unassign the card from a mission.
		/// </summary>
		public void Unassign()
		{
			this.Assigned = false;
			this.OnCardUnassigned();
		}
		#endregion

		#region On Card Assigned
		/// <summary>
		/// Fire the card assigned event.
		/// </summary>
		protected virtual void OnCardAssigned()
		{
			if (this.CardAssigned != null)
				this.CardAssigned(this);
		}
		#endregion

		#region On Card Unassigned
		/// <summary>
		/// Fire the card unassigned event.
		/// </summary>
		protected virtual void OnCardUnassigned()
		{
			if (this.CardUnassigned != null)
				this.CardUnassigned(this);
		}
		#endregion

		#region On Status Changed
		/// <summary>
		/// Fire the status changed event.
		/// </summary>
		/// <param name="status">The new card status.</param>
		protected virtual void OnStatusChanged(CardStatus status)
		{
			if (this.StatusChanged != null)
				this.StatusChanged(status);
		}
		#endregion

		#region Can Assign
		/// <summary>
		/// This method checks wether or not the player can assign a card to the mission.
		/// </summary>
		/// <returns>Returns true if the card can be assigned to a mission.</returns>
		public virtual bool CanAssign()
		{
			bool canAssign = false;

			if (this.Owner.HasPriority)
			{
				if ((this.InputStatus == InputStatus.AllowAssign) && (this.Status == CardStatus.Unassigned))
					canAssign = true;
			}

			return canAssign;
		}
		#endregion

		#region Stop
		/// <summary>
		/// Stop the card.
		/// </summary>
		public void Stop()
		{
			// TODO: Implement stop and block though modifiers
			this.Status = Wormhole.Engine.CardLibrary.CardStatus.Stopped;
		}
		#endregion
	}
}
